package main

import (
	"crypto/md5"
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"os"
	"os/exec"
	"strings"
)

func main() {
	fmt.Println("md5/sha for string ,bianry array and file.")

	var astr string = "Calc the md5 for this string."
	fmt.Println("calc md5/sha1 for string:", astr)
	var zz [md5.Size]byte = md5.Sum([]byte(astr))
	var ss [sha1.Size]byte = sha1.Sum([]byte(astr))
	//Tip1: 不可用直接传[md5.Size]byte类型给这个函数，这个函数要求的是参数类型是[]byte。
	//用zz[:]取切片转一下。
	md5str := hex.EncodeToString(zz[:])
	sha1str := hex.EncodeToString(ss[:])
	fmt.Println("str md5:", md5str)
	fmt.Println("str sha1:", sha1str)

	var binArray = [...]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	//Tip2: 同上原因，md5.Sum要的是一个切片，所以需要把数组全部元素作为切片。
	fmt.Println("calc md5/sha1 for binaray array:", binArray)
	zz = md5.Sum(binArray[:])
	ss = sha1.Sum(binArray[:])
	md5str = hex.EncodeToString(zz[:])
	sha1str = hex.EncodeToString(ss[:])
	fmt.Println("binarray md5:", md5str)
	fmt.Println("binarray sha1:", sha1str)

	// 测试获取文件的md5值
	// 先准备一个文件
	var cmd *exec.Cmd = exec.Command("cmd.exe", "/c", "echo ThisIsATestString > D:\\tmp123.txt")
	cmd.Run()

	var file *os.File
	var err error
	file, err = os.Open("D:\\tmp123.txt")
	if err != nil {
		fmt.Println(err.Error())
	} else {
		var b []byte = make([]byte, 100)
		cnt, err := file.Read(b)
		file.Close()
		if err != nil {
			fmt.Println(err.Error())
		} else {
			fmt.Println("Read file bytes:", cnt)
			// 注意这里不要直接用切片b，前面定义b的时候长度定义为100
			// 切片中除了读取出的文件内容之外的其他内容都被初始化成了0x00
			zz = md5.Sum(b[:cnt])
			ss = sha1.Sum(b[:cnt])
			md5str = hex.EncodeToString(zz[:])
			sha1str = hex.EncodeToString(ss[:])
			md5str = strings.ToUpper(md5str)
			sha1str = strings.ToUpper(sha1str)
			fmt.Println("md5 of file is :", md5str, ", md5 is correct:", md5str == "A68703058EC36399FC98E5B521807391")
			fmt.Println("sha1 of file is :", sha1str, ", sha1 is correct:", sha1str == "917294F8B1D9AF66CB4A4EE795AA1EE47F8D1AE5")
		}
	}

}
